package com.zbmy.plugin.im.server.core.session;

import io.netty.channel.Channel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.zbmy.plugin.im.server.core.model.ChannelInfo;

/**
 * 
 * Netty用户Session相关
 * @ClassName: UserSessionManger    
 * @author 杨乐平    
 * @date 2018年4月28日 下午5:25:51    
 * @version  v 1.0
 */
public final class UserSessionManger {
	
	public final static AttributeKey<ChannelInfo> SESSION_KEY = AttributeKey.valueOf("channelInfo");
	
	/**
	 * 用于存放在线用户的username和channel
	 */
    public final static Map<String, Channel> userToChannelOnlineMap =   new ConcurrentHashMap<String, Channel>();
    
    /**
     * 
     * 使用channel的attr，在channel中保存客户端info
     * @author 杨乐平    
     * @Title: addChannelSession    
     * @param channel
     * @param session
     * @return 
     * @Return: boolean 返回值
     */
	public static boolean addChannelInfo(Channel channel, ChannelInfo channelInfo) {
		Attribute<ChannelInfo> channelInfoAttr = channel.attr(SESSION_KEY);
		return channelInfoAttr.compareAndSet(null, channelInfo);
	}
	
	/**
	 * 
	 * 使用channel的attr，在channel中保存客户端info   
	 * @author 杨乐平    
	 * @Title: getSessionBy    
	 * @param channel
	 * @return 
	 * @Return: ChannelInfo 返回值
	 */
	public static ChannelInfo getChannelInfo(Channel channel) {
		Attribute<ChannelInfo> channelInfoAttr = channel.attr(SESSION_KEY);
		return channelInfoAttr.get() ;
	}
	
	public static void removeChannelInfo(Channel channel) {
		Attribute<ChannelInfo> channelInfoAttr = channel.attr(SESSION_KEY);
		channelInfoAttr.remove();
	}
	
	/**
	 *  全局channel group
	 */
	public static final ChannelGroup channelGroup = new DefaultChannelGroup("ChannelGroups",
			GlobalEventExecutor.INSTANCE);
	
	/**
	 * 每个登入的客户端分配一个token，用于长连接
	 */
	public  static final Set<Long> tokenSet = new HashSet<>();
	
	/**
	 * 
	 * 生成1个token   
	 * @author 杨乐平    
	 * @Title: generateToken    
	 * @return 
	 * @Return: Long 返回值
	 */
	public static Long generateToken() {
        Long token;
        Random random = new Random();
        while (tokenSet.contains(token = random.nextLong())) {
            token = random.nextLong();
        }
        return token;
    }
}
